Skip to content

JS DOM 操作

DOM 是什么

shell
浏览器将 HTML/XML 解析为文档对象模型(Document Object Model):由节点与对象组成的树结构(DOM 树),
JavaScript 可通过 DOM API 访问、修改文档的内容、结构与样式。

下文为日常 CRUD / 样式 / 事件 中与开发最相关的写法速查。

要点速览

shell
DOM(文档对象模型)是操作 HTML/XML 文档的接口,
常见的 DOM 操作有:DOM 元素的增删改查操作、DOM 元素属性的增删改查、修改DOM元素内容、修改元素样式style/class、DOM 事件的绑定和解绑

# 开发中
获取元素优先用 querySelector/querySelectorAll,语法和 CSS 一致,最灵活;
样式 / 类名优先用 classList,比直接操作 style 更优雅;
动态内容优先用 textContent,比 innerHTML 更安全;
事件绑定用 addEventListener,支持多事件、解绑。

拓展

shell
# DOM 节点和DOM 元素的区别
元素是节点的一种,节点不一定是元素
Node DOM 所有内容的统称,包含元素、文本、空格、换行、注释。
Element Node 的子集,仅指 HTML 标签元素。
即:节点包罗万象,元素只认标签;不带 Element 拿节点(带空格),带 Element 拿干净元素。

# HTMLCollection 与 NodeList 的核心区别
HTMLCollection 只包含 HTML 元素标签(<div><p><a> 等),不包含文本、注释等。
NodeList 包含所有节点:元素节点(标签)、文本节点(空格、文字)、注释节点 <!-- -->

拿到 HTMLCollection
getElementsByClassName()
getElementsByTagName()
element.children
拿到 NodeList
querySelectorAll()(静态,最常用)
getElementsByName()(动态)
element.childNodes(包含文本、注释)

HTMLCollection 是动态的,只存元素,不能 forEach
NodeList 大多是静态的,存所有节点,能 forEach
开发优先用 querySelectorAll,因为静态更安全、可控


# 查询 / 获取元素(最常用
1. 通过 ID 获取(唯一,返回单个元素)
document.getElementById('box');

2. 通过 class 名获取(返回 HTMLCollection 类数组)
document.getElementsByClassName('item');

3. 通过标签名获取(返回 HTMLCollection)
document.getElementsByTagName('div');

4. 通过 name 属性获取
document.getElementsByName('username');

5. CSS 选择器(返回第一个匹配元素,最灵活)
document.querySelector('#box .item');

6. CSS 选择器(返回所有匹配元素的 NodeList)
document.querySelectorAll('.list li');

7. 获取特殊元素
document.documentElement; // 获取 html 根标签
document.body;            // 获取 body 标签
document.head;            // 获取 head 标签

# 创建新元素
1. 创建元素节点
const div = document.createElement('div');
2. 创建文本节点
const text = document.createTextNode('我是文本');

# 插入元素
const parent = document.querySelector('.parent');
const child = document.createElement('p');

1. 追加到父元素末尾
parent.appendChild(child);

2. 插入到指定子元素前面
parent.insertBefore(child, 参考元素);

3. 现代方法(更直观)
parent.prepend(child); 插入到父元素开头
element.before(child);  插入到目标元素前面
element.after(child);   插入到目标元素后面

# 删除元素
const box = document.getElementById('box');
方法1:元素自己删除自己(推荐)
box.remove();

方法2:父元素删除子元素
box.parentNode.removeChild(box);

# 替换 / 克隆元素
1. 替换元素
parent.replaceChild(新元素, 被替换元素);

2. 克隆元素
false:只克隆标签(默认)
true:深度克隆(标签+内容+样式)
const clone = box.cloneNode(true);

# 修改元素内容
const box = document.querySelector('#box');

1. 纯文本内容(不会解析 HTML,安全)
box.textContent = '纯文本';

2. 解析 HTML 标签(慎用,有 XSS 风险)
box.innerHTML = '<strong>加粗文本</strong>';

3. 表单元素的值(input/textarea/select)
input.value = '输入框内容';

# 修改元素属性
const img = document.querySelector('img');

1. 原生属性直接操作
img.src = '图片地址';
img.alt = '图片描述';
a.href = '链接地址';

2. 自定义属性
设置
img.setAttribute('data-id', '1001');
获取
img.getAttribute('data-id');
删除
img.removeAttribute('data-id');

3. 直接操作 data-* 自定义属性(推荐)
img.dataset.id = '1001'; // 等价于 data-id
console.log(img.dataset.id);

# 修改元素样式(行内样式)
const box = document.querySelector('#box');

1. 单个样式(驼峰命名,如 background-color backgroundColor)
box.style.color = 'red';
box.style.backgroundColor = '#fff';
box.style.width = '200px';

2. 获取计算后的样式(最终生效的样式,包括 css 类)
const styles = window.getComputedStyle(box);
console.log(styles.width);

# 操作类名(推荐)
1. 添加类
box.classList.add('active', 'show');

2. 删除类
box.classList.remove('active');

3. 切换类(有则删,无则加)
box.classList.toggle('active');

4. 判断是否包含类
box.classList.contains('active'); // 返回 true/false

# DOM 事件操作
const btn = document.querySelector('button');

1. 直接绑定(覆盖式,只能绑定一个)
btn.onclick = function() { alert('点击'); }

2. 事件监听(推荐,可绑定多个)
btn.addEventListener('click', 回调函数);
鼠标事件
btn.addEventListener('mouseenter', ()=>{});
键盘事件
input.addEventListener('keydown', ()=>{});

3. 解绑事件
btn.removeEventListener('click', 回调函数);

4. 事件对象常用方法
function handle(e) {
  e.preventDefault(); // 阻止默认行为(如a标签跳转)
  e.stopPropagation(); // 阻止事件冒泡
  e.target; // 触发事件的元素
}